<script setup lang="ts">
import {onMounted, onUnmounted, ref, useTemplateRef, watch} from "vue";
import { type Props } from "./index";
import { WxBiaoQings } from "@/utils/wxBiaoQing.ts";
import {
  Search,
  MoreFilled,
  View,
  PictureFilled,
  Film,
  Check, Close
} from "@element-plus/icons-vue";
import {
  type MaterialInfoResult,
  resourcesMaterialManageApi
} from "@/api/zyApi.ts";
import {
  createZYImageUrl,
  createZYPreviewImageUrl,
  createZYPreviewVideoCoverUrl
} from "@/utils/util.ts";
import type {LowercaseFirst} from "@/types";
import {dayjs, ElMessageBox} from "element-plus";
import AddMaterialResource from "./AddMaterialResource.vue";
import EditMaterialResource from "./EditMaterialResource.vue";
import { usePreviewVideo } from "@/components/videoView";

defineOptions({
  name: "MessageInput"
})

const props = defineProps<Props>();
const emit = defineEmits(["update:modelValue"]);
const data = ref<string>(props.modelValue); // 输入框数据
const showEmojis = ref<boolean>(false); // 显示icon图标
const emojisList = ref<any[]>([]);// 常用表情
const inputElRef = useTemplateRef("inputElRef");
const addMaterialResourceRef = useTemplateRef("addMaterialResourceRef"); // 添加资源组件实例
const editMaterialResourceRef = useTemplateRef("editMaterialResourceRef"); // 编辑资源组件实例
const materialDialog = ref<boolean>(false); // 显示素材库
const materialStatus = ref<number>(2); // 弹窗类型 2图片 4视频
const dataList = ref<LowercaseFirst<MaterialInfoResult>[]>([]); // 素材数据
const isLoading = ref<boolean>(false);
const selectList = ref<LowercaseFirst<MaterialInfoResult>[]>([]); // 选中的素材列表
const selectEditData = ref<LowercaseFirst<MaterialInfoResult>>(); // 编辑的数据
const previewList = ref<string[]>([]);// 图片预览列表数据
const showViewer = ref<boolean>(false); // 显示图片预览窗口
const search = ref<string>(""); // 搜索关键字
const page = ref({
  pageNumber: 1,
  pageSize: 16,
  total: 0
});

/**
 * 赋值操作
 * @param str
 */
const setValue = (str: string) => {
  let divel = inputElRef.value?.$el as HTMLElement;
  let el = divel.getElementsByClassName('el-textarea__inner')[0] as any;
  if (el) {
    let startPos = el.selectionStart;
    let endPos = el.selectionEnd;
    if (startPos === undefined || endPos === undefined) return;
    let txt = el.value;
    el.value = txt.substring(0, startPos) + str + txt.substring(endPos);
    el.selectionStart = startPos + str.length;
    el.selectionEnd = startPos + str.length;
    data.value = el.value;
    emit('update:modelValue', data.value);
    inputElRef.value && inputElRef.value.focus();
  }
};

/**
 * 选择素材确定操作
 */
const confirmHandler = () => {
  let result = "";
  selectList.value.forEach((item) => {
    result += `[${materialStatus.value === 2 ? '图片' : '视频'}=${item.name}]`;
  });
  if (result === "") return;
  setValue(result);
  closeTempHandler();
};

/**
 * 编辑素材
 */
const editMaterialHandler = (item: LowercaseFirst<MaterialInfoResult>) => {
  selectEditData.value = item;
  editMaterialResourceRef.value && editMaterialResourceRef.value.open();
}

/**
 * 删除素材
 */
const delMaterialHandler = (item: LowercaseFirst<MaterialInfoResult>) => {
  ElMessageBox.confirm(
      '是否删除素材?',
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
  ).then(() => {
      resourcesMaterialManageApi.Delete(item.id)
          .then(() => {
            // 删除本地列表数据和选中数据，优化网络请求
            const index = dataList.value.findIndex(item => item.id === item.id);
            const selectIndex = selectList.value.findIndex(item => item.id === item.id);
            index > -1 && (dataList.value.splice(index, 1));
            selectIndex > -1 && (selectList.value.splice(selectIndex, 1));
          })
  })
};

/**
 * 上传素材处理
 */
const uploadHandler = () => {
  addMaterialResourceRef.value && addMaterialResourceRef.value.open();
};

/**
 * 预览处理
 * @param item
 */
const handlePreview = (item: LowercaseFirst<MaterialInfoResult>) => {
  // 处理图片
  if (item.type === "img") {
    previewList.value = [item.url];
    showViewer.value = true;
  }
  // 处理视频
  if (item.type === "video") {
    const [openUrl] = usePreviewVideo();
    openUrl.OpenUrl(item.url);
  }
};

/**
 * 选中处理
 * @param item
 */
const handleSelected = (item: LowercaseFirst<MaterialInfoResult>) => {
  // todo 判断选择上限
  item.isSelect = true;
  const index = selectList.value.findIndex(select => select.id === item.id);
  if (index > -1) {
    selectList.value.splice(index, 1);
    return;
  }
  selectList.value.push(item);
};

// 是否选中
const isSelected = (item: any) => {
  return selectList.value.findIndex(w => w.id == item.id) >= 0;
};

// 获取预览地址
const getPreviewUrl = (data: MaterialInfoResult) => {
  if (data.MaterialType == 2) {
    return createZYPreviewImageUrl(data.FileId, '180*130');
  }
  if (data.MaterialType == 4) {
    return createZYPreviewVideoCoverUrl(data.FileId, '180*130');
  }
  return '';
};

/**
 * 获取素材列表
 * @param list
 */
const getDatas = (list: MaterialInfoResult[]) => {
  dataList.value = [];
  list.forEach((item: MaterialInfoResult) => {
    const oldData = dataList.value.find((w) => w.id === item.Id);
    const newData: Partial<LowercaseFirst<MaterialInfoResult>> = {
      id: item.Id,
      name: item.Name,
      time: item.UpdateTime,
      type: item.MaterialType == 2 ? 'img' : 'video',
      previewUrl: getPreviewUrl(item),
      url: createZYImageUrl(item.FileId),
      fileId: item.FileId,
      data: item,
    };
    if (!oldData) {
      newData.isSelect = false;
      dataList.value.push(newData as any);
    } else {
      Object.assign(oldData, newData);
    }
  });
}

/**
 * 加载数据
 */
const loadDate = () => {
  isLoading.value = true;
  resourcesMaterialManageApi.GetMaterialInfos({
    PageIndex: page.value.pageNumber,
    PageSize: page.value.pageSize,
    MaterialType: materialStatus.value,
    Keyword: search.value
  })
      .then((res) => {
        page.value.total = res.TotalNumber;
        getDatas(res.Datas);
      })
      .finally(() => {
        isLoading.value = false;
      })
};

/**
 * 显示弹窗类型
 * @param num
 */
const showMaterialHandler = (num: number) => {
  materialStatus.value = num;
  showEmojis.value = false;
  materialDialog.value = true;
  loadDate();
};

/**
 * 搜索处理
 */
const searchHandler = () => {
  showMaterialHandler(materialStatus.value);
};

/**
 * 获取表情
 * @param item
 */
const getIconHandler = (item: { Name: string; Bq: string }) => {
  const index = emojisList.value.findIndex((emojis) => emojis.Name === item.Name);
  if (index !== -1) { // 将之前用过的emojis替换替换掉放置最前面
    emojisList.value.splice(index, 1);
    emojisList.value.unshift(item);
  } else {
    emojisList.value.unshift(item);
  }
  // 常用的保留16个常用表情
  emojisList.value = emojisList.value.slice(0, 16);
  const name = `[${item.Name}]`;
  setValue(name);
  // 关闭emojis列表
  showEmojis.value = false;
};

/**
 * 初始化数据
 */
const initValue = () => {

};

/**
 * 输入时触发
 */
const inputHandler = (e: any) => {
  emit('update:modelValue', data.value);
};

/**
 * 关闭弹窗
 */
const closeTempHandler = () => {
  materialDialog.value = false;
  selectList.value = [];
};

onMounted(() => {
  initValue();
});

/**
 * 监听器
 */
const stopWatch = watch(
    ()=> page.value.pageNumber,
    () => {
      loadDate();
    }
);

const stopWatch2 = watch(
    () => props.modelValue,
    (val) => {
      data.value = val;
    }
);

onUnmounted(() => {
  stopWatch && stopWatch();
  stopWatch2 && stopWatch2();
  showEmojis.value = false;
});
</script>

<template>
  <div class="message-layout">
    <el-input
      ref="inputElRef"
      type="textarea"
      class="message-container"
      clearable
      :rows="9"
      v-model="data"
      @input="inputHandler"
      resize="none"
    />
    <div class="message-func">
      <img class="icon-item" alt="" src="/src/assets/image/serviceSystem/emojia.svg" @click="showEmojis = !showEmojis">
      <transition name="el-zoom-in-top">
        <div
            id="robotList"
            ref="robotList"
            v-if="showEmojis"
            class="bg-white absolute w-375px bottom-0px rounded-4px p-15px box-border h-283px z-[99] border-1px-solid-#717EEA overflow-auto"
        >
          <p v-if="emojisList.length > 0">常用表情</p>
          <el-space wrap :size="14">
            <img
                class="wxBQImg"
                v-for="item in emojisList"
                :src="item.Bq"
                width="30"
                height="30"
                alt=""
                @click="getIconHandler(item)"
            />
          </el-space>
          <p>默认表情</p>
          <el-space wrap :size="14">
            <img
                class="wxBQImg"
                v-for="item in WxBiaoQings"
                :src="item.Bq"
                width="30"
                height="30"
                alt=""
                @click="getIconHandler(item)"
            />
          </el-space>
        </div>
      </transition>
      <img class="icon-item" src="/src/assets/image/serviceSystem/pic.svg" @click="showMaterialHandler(2)" alt="">
      <img class="icon-item" src="" @click="showMaterialHandler(4)" alt="">
    </div>
  </div>
  <el-dialog
    v-model="materialDialog"
    title="素材库"
    width="1000"
    append-to-body
    align-center
    :show-close="false"
    @close="closeTempHandler"
  >
    <div class="demo-image__preview">
      <add-material-resource ref="addMaterialResourceRef" @success="loadDate" />
      <edit-material-resource ref="editMaterialResourceRef" :edit-id="selectEditData?.id" :edit-name="selectEditData?.name" @success="loadDate" />
      <el-image-viewer hide-on-click-modal @close="() => { showViewer = false }" v-if="showViewer" :url-list="previewList"/>
    </div>
    <div class="header">
      <el-button plain @click="uploadHandler">上传素材</el-button>
      <el-button type="primary">{{ materialStatus === 2 ? "图片" : "视频" }}</el-button>
      <el-input v-model="search" style="width: 200px;margin: 0px 10px" clearable></el-input>
      <el-button :icon="Search" type="primary" @click="searchHandler"></el-button>
    </div>
    <div class="material-main">
      <el-scrollbar :height="400" v-loading="isLoading" v-if="dataList.length > 0">
        <div class="content-list">
          <div class="list-item" v-for="item in dataList" :key="item.id">
            <div class="list-item-selected" v-if="isSelected(item)">
              <div class="list-item-selected-bg"></div>
              <el-icon class="list-item-selected-icon" :size="24">
                <Check />
              </el-icon>
            </div>
            <div class="img-box" @click="handleSelected(item)">
              <el-image class="img" :src="item.previewUrl" :preview-src-list="[item.url]" fit="cover" />
              <el-icon :size="28" class="type-icon">
                <el-icon>
                  <PictureFilled v-if="item.type == 'img'" />
                  <Film v-if="item.type == 'video'" />
                </el-icon>
              </el-icon>
              <div class="option-func">
                <el-space class="option-func-box">
                  <el-icon :size="30" class="func-icon" @click.stop="handlePreview(item)">
                    <View />
                  </el-icon>
                </el-space>
              </div>
            </div>
            <div class="options">
              <div class="left">
                <div class="title">{{ item.name }}</div>
                <div class="time">{{ dayjs(item.time).format("YYYY-MM-DD hh:mm") }}</div>
              </div>
              <div class="rigth">
                <el-dropdown :hide-on-click="false">
                  <el-button text style="margin-top: 5px;">
                    <el-icon>
                      <MoreFilled />
                    </el-icon>
                  </el-button>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item @click="editMaterialHandler(item)">修改</el-dropdown-item>
                      <el-dropdown-item @click="delMaterialHandler(item)">删除素材</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </div>
          </div>
        </div>
      </el-scrollbar>
      <el-empty v-else description="暂无数据" />
    </div>
    <template #footer>
      <div class="footer-layout">
        <div class="footer-left">
          <el-pagination
            background
            layout="prev, pager, next"
            :total="page.total"
            v-model:page-size="page.pageSize"
            v-model:current-page="page.pageNumber"
          />
        </div>
        <div class="footer-right">
          <el-text style="margin-right: 10px">点击选择素材</el-text>
          <el-popover placement="top" :width="200" trigger="hover">
            <template #reference>
              <el-button>已选中（{{ selectList.length }}）个</el-button>
            </template>
            <el-scrollbar :max-height="240">
              <div class="selected-list-box" v-if="selectList.length > 0">
                <div class="selected-list-item" v-for="item in selectList" :key="item.id">
                  <div>
                    <ElSpace>
                      <el-icon :size="16" style="vertical-align:middle;">
                        <PictureFilled v-if="item.type == 'img'" />
                        <Film v-if="item.type == 'video'" />
                      </el-icon>
                      <span style="margin-top: 2px;">{{ item.name }}</span>
                    </ElSpace>
                  </div>
                  <div>
                    <el-icon class="selected-list-item-icon" :size="18" @click="handleSelected(item)">
                      <Close />
                    </el-icon>
                  </div>
                </div>
              </div>
              <div style="text-align: center;" v-else>无数据</div>
            </el-scrollbar>
          </el-popover>
          <el-button @click="closeTempHandler">关闭</el-button>
          <el-button type="primary" @click="confirmHandler">确定</el-button>
        </div>
      </div>
    </template>
  </el-dialog>
</template>

<style scoped lang="less">
@messageHeight: 32px;
.message-layout {
  width: 100%;
  height: 100%;
  .message-container {
    width: 100%;
    height: 100%;
      :deep(.el-textarea__inner) {
        height: 100% !important;
    }
  }
  .message-func {
    height: @messageHeight;
    display: flex;
    align-items: center;
    .icon-item {
      width: 20px;
      height: 20px;
      margin-right: 10px;
    }
  }
}
.material-main {
  padding: 10px;
  .content-list {
    width: 100%;
    height: 100%;
    display: flex;
    flex-wrap: wrap;
    .list-item {
      position: relative;
      margin-right: 5px;
      width: 195px;
      height: 195px;
      border: 1px #f0f0f2 solid;
      border-radius: 5px;
      //padding: 2px;
      &:hover {
        border-color: #409eff;
      }
      .img-box {
        width: 100%;
        height: 145px;
        position: relative;
        .img {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }
        .type-icon {
          position: absolute;
          bottom: 5px;
          right: 5px;
        }
        .option-func {
          position: absolute;
          top: 0;
          right: 0;
          bottom: 0;
          left: 0;
          .option-func-box {
            visibility: hidden;
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            color: #fff;
            .func-icon {
              &:hover {
                cursor: pointer;
                color: #409eff;
              }
            }
          }
          &:hover {
            background-color: rgba(#000000, 0.4);
          }
          &:hover .option-func-box {
            visibility: visible;
          }
        }
      }
      .options {
        padding: 3px 8px 0 8px;
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        .left {
          display: flex;
          flex-direction: column;
          .title {
            font-size: 14px;
          }
          .time {
            padding-top: 4px;
            font-size: 12px;
            color: #8c8c8c;
          }
        }
      }
      .list-item-selected {
        position: absolute;
        right: 0px;
        top: 0px;
        cursor: pointer;
        .list-item-selected-bg {
          width: 0;
          height: 0;
          border: 24px solid transparent;
          border-right: 24px solid #36ad6a;
          transform: rotate(135deg);
          position: absolute;
          right: -24px;
          top: -24px;
          cursor: pointer;
          z-index: 100;
        }
        .list-item-selected-icon {
          color: #fff;
          z-index: 101;
          right: -5px;
          top: -5px;
        }
      }
    }
  }
}

.footer-layout {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  .footer-left {
    width: 50%;
    display: flex;
    align-items: center;
    justify-content: flex-start;
  }
  .footer-right {
    width: 50%;
  }
}
</style>